%html(lang='fr') %head %meta(charset='utf-8') %meta(name='viewport' content='width=1024') %meta(name='apple-mobile-web-app-capable' content='yes') %title Ruby on Rails, c'est magique! %meta(name='description' content='Ruby on Rails est un outillage de développement web, permettant de développer bien plus vite que la plupart des autres existants') %meta(name='author' content='Emmanuel Charpentier') %link(href='http://fonts.googleapis.com/css?family=Open+Sans:regular,semibold,italic,italicsemibold|PT+Sans:400,700,400italic,700italic|PT+Serif:400,700,400italic,700italic' rel='stylesheet') %link(href="css/styles.css" rel="stylesheet") %link(href="css/slides.css" rel="stylesheet") %link(href="js/highlight/styles/sunburst.css" rel="stylesheet") %link(rel="shortcut icon" href="favicon.png") %link(rel="apple-touch-icon" href="apple-touch-icon.png") %body(class="impress-not-supported") .fallback-message %p Votre navigateur ne supporte pas les fonctionnalités requises par cette présentation, donc vous êtes présentés avec une version simplifiée de cette présentation. %p Pour une meilleur expérience, s'il vous plait utilisez l'une des dernières versions des navigateurs Chrome, Safari ou Firefox. #impress #title.step %h2 Ruby on Rails c'est %h1 Magique! .footnote .author echarp 2012 RMLL Genève .step(data-rotate-y='90') %h2 echarp %h3 aka «Emmanuel Charpentier» %ul %li informaticien depuis 1998 %li dans le monde %a(href='http://java.com') %img(src='https://upload.wikimedia.org/wikipedia/commons/thumb/a/a4/Java_logo_and_wordmark.svg/200px-Java_logo_and_wordmark.svg.png' alt='Logo RoR' style='width: 1.4em') depuis 1999 %li fan de %a(href='http://rubyonrails.org') %img(src='http://rubyonrails.org/images/rails.png' alt='Logo RoR') depuis 2005 %li indépendant: acoeuro.com %li %a(href='http://april.org') %img(src='http://www.april.org/sites/default/themes/zen_april/logo.png' alt='Logo April') revue de presse .step(data-x='-1000' data-y='-1000') %h3 Les fondements de RoR » %h2 Ruby! %pre %code.ruby :preserve irb(main):001:0> puts 'hello world' hello world => nil irb(main):002:0> puts("high \#{2+3}") high 5 => nil .step(data-x='-2000' data-y='-2000' data-z='1000') %h2 Ruby est %ul %li concis %li lisible %li expressif %li vraiment objet %li typé en "canard" %li méta programmable %li riche d'une belle librairie %li héritier de perl et smalltalk .step(data-x='-3000' data-y='-3000' data-z='2000') %h2 Mais... %p Plutôt lent %p Pas aussi utilisé que PHP %p Pas aussi "sérieux" que java %p Dur à refactorer, car typage original %p Pas toujours bien packagé dans l'OS .step(data-x='-4000' data-y='-4000' data-z='3000') %h2 Heureusement %p Ruby 2 arrive %p et apporte une machine virtuelle %p ... comme java :) %p (note, ruby 1.9 EST ruby 2 :) .step(data-x='1000' data-y='-1000') %h2 Ruby on Rails %h3 Et le développeur web devient productif %p Outillage web sur le language Ruby %p Modèle Vue Contrôleur %p Version 3.2 %p Copié mais jamais dépassé :) %p utilisé par: github, twitter, scribd, groupon, shopify, basecamp... .step(data-x='1000' data-y='-1000' data-z='2000') %h2 Pré requis développement %ul %li ruby: apt-get install ruby %li sqlite: apt-get install sqlite3 %li rails: gem install rails %p Pas besoin de %ul %li créer une base de données %li mettre en place un serveur web .step(data-x='1000' data-y='-1000' data-z='3000') %h2 Nouveau projet %pre %code.bash :preserve $ rails new demo $ ... $ cd demo $ ./script/rails c => Booting WEBrick => Rails 3.2.6 application starting in development on http://0.0.0.0:3000 => Call with -d to detach => Ctrl-C to shutdown server [2012-07-06 17:12:16] INFO WEBrick 1.3.1 [2012-07-06 17:12:16] INFO ruby 1.9.3 (2012-04-20) [x86_64-linux] [2012-07-06 17:12:16] INFO WEBrick::HTTPServer#start: pid=31378 port=3000 .step(data-x='1000' data-y='-1000' data-z='4000') %img(src='img/nouveau_projet.png' alt="Copie d'écran navigateur pour le nouveau projet") .step(data-y='-1000') %h2 Première page %pre %code.bash :preserve $ ./script/rails generate scaffold User name:string email:string $ ... $ rake db:migrate == CreateUsers: migrating ============ -- create_table(:users) -> 0.0020s == CreateUsers: migrated (0.0022s) ======= $ rake db:migrate:status database: db/development.sqlite3 Status Migration ID Migration Name -------------------------------------------------- up 20120706153508 Create users .step(data-y='-500' data-z='-500' data-rotate-x='90') %img(src='img/users_index.png' alt="Users index") .step(data-x='500' data-y='-1000' data-z='-500' data-rotate-x='90' data-rotate-y='-90') %img(src='img/users_new.png' alt="Users new") .step(data-y='-1600' data-z='-500' data-rotate='180' data-rotate-x='270') %img(src='img/users_show.png' alt="Users show") .step(data-x='-500' data-y='-1000' data-z='-500' data-rotate='450' data-rotate-y='90') %img(src='img/users_index_2.png' alt="Users index 2") .step(data-x='-1000' data-y='1000') %h2 Base de données %h3 Évolutions et maintenance du schéma %p Pas de SQL %p Déploiements %p Graines de données %p Migrations du schéma %p Versions... et rollback %p Environnements .step(data-x='-1000' data-y='1500' data-z='-500' data-rotate-x='90') %pre.database.yml %code.ruby config/database.yml :preserve # SQLite version 3.x # gem install sqlite3 # # Ensure the SQLite 3 gem is defined in your Gemfile # gem 'sqlite3' development: adapter: sqlite3 database: db/development.sqlite3 pool: 5 timeout: 5000 # Warning: The database defined as "test" will be erased and # re-generated from your development database when you run "rake". # Do not set this db to the same as development or production. test: adapter: sqlite3 database: db/test.sqlite3 pool: 5 timeout: 5000 production: adapter: sqlite3 database: db/production.sqlite3 pool: 5 timeout: 5000 .step(data-x='-1000' data-y='2000' data-rotate-x='180') %h2 Les migrations %p Créer et faire évoluer le schéma de la base de données... en ruby, %pre %code.bash :preserve $ ./script/rails generate migration AddPseudoToUser pseudo:string:index invoke active_record create db/migrate/20120706205313_add_pseudo_to_user.rb $ rake db:migrate == AddPseudoToUser: migrating ======================================== -- add_column(:users, :pseudo, :string) -> 0.0015s -- add_index(:users, :pseudo) -> 0.0007s == AddPseudoToUser: migrated (0.0024s) =============================== .step(data-x='-1000' data-y='1500' data-z='500' data-rotate-x='270') %h2 Migration %pre %code.ruby :preserve class AddPseudoToUser < ActiveRecord::Migration def change add_column :users, :pseudo, :string add_index :users, :pseudo end end %h3 Méfiance %p Intégrité référentielle! %p Évolutions dans les données! .step(data-y='1000') %h2 Ressources REST %p URL » vues » contrôleur » modèle %pre config/routes.rb %pre %code.ruby :preserve Demo::Application.routes.draw do resources :users end %p Les URL obtenues %pre %code.bash :preserve $ rake routes users GET /users(.:format) users#index POST /users(.:format) users#create new_user GET /users/new(.:format) users#new edit_user GET /users/:id/edit(.:format) users#edit user GET /users/:id(.:format) users#show PUT /users/:id(.:format) users#update DELETE /users/:id(.:format) users#destroy .step(data-y='1500' data-z='-500' data-rotate-x='90') %pre %code :preserve demo/app/ ├── assets │   └── ... ├── controllers │   ├── application_controller.rb │   └── users_controller.rb ├── helpers │   ├── application_helper.rb │   └── users_helper.rb ├── mailers ├── models │   └── user.rb └── views ├── layouts │   └── application.html.erb └── users ├── edit.html.erb ├── _form.html.erb ├── index.html.erb ├── new.html.erb └── show.html.erb .step(data-y='2000' data-rotate-x='180') %h2 Organisation %p Propre et consistant %p Multi protocoles: HTML, JSON, XML... %p Gestion automatique de nombreuses problématiques: %ul %li session (en cookie par défaut!) %li notifications utilisateur, erreurs %li paramètres, fichiers uploadés %li ... .step(data-x='1000' data-y='1000') %h2 Pipeline %img(src='img/pipeline_dev.png' alt='Les assets en développement') .step(data-x='1000' data-y='1500' data-z='-500' data-rotate-x='90') %h2 Production %img(src='img/pipeline_prod.png' alt='Les assets en production') .step(data-x='1000' data-y='2000' data-rotate-x='180') %h2 mod_expires %pre %code.bash :preserve <IfModule expires_module> ExpiresActive On <FilesMatch "\.(ico|gif|jpe?g|png|js|css|fla|swf|JPG)$"> ExpiresDefault "access plus 1 year" Header set Cache-Control "public" FileETag None </FilesMatch> </IfModule> .step(data-x='1000' data-y='1500' data-z='500' data-rotate-x='270') %h2 Navigation %img(src='img/pipeline_prod_2.png' alt='Les assets en production, après chargement initial') .step(data-x='-1000') %h2 Documentation %p %a(href='http://guides.rubyonrails.org') %img(src='img/rails_guides_logo.gif' alt='Guides rails') %img(src='img/rails_guides.png' alt='Liste des guides') .step(data-x='1000') %h2 Philosophie %ul %li TIMTOWTDI %li DRY %li CoC %li Fun #overview.step(data-scale='3.6') .hint %p Appuyer sur la touche espace ou une flèche pour naviguer %script(src='js/impress.js') %script(src='js/highlight/highlight.pack.js') :javascript if ("ontouchstart" in document.documentElement) { document.querySelector(".hint").innerHTML = "

Cliquez sur gauche ou droite pour naviguer

"; } impress().init(); hljs.initHighlightingOnLoad();